<template>
    <view>
        <uni-popup ref="smsPopup" type="center" @change="popupChange" :is-mask-click="false">
            <view class="sms-manager">
                <view class="sms-manager--header mb">群发短信</view>
                <uni-forms :label-width="100" :modelValue="smsDataModel" ref="smsForm">
                    <uni-forms-item label="目标对象" v-if="toType === 'user'">
                        <view v-if="isSelectedReceiver">当前已选择{{ receiver.length }}人</view>
                        <view v-else>全部用户</view>
                        <view class="sms-data-tip">如需给指定用户发送，请在列表选择要发送的用户。</view>
                    </uni-forms-item>
                    <uni-forms-item label="目标对象" v-else>
                        <view>当前已选择{{ receiver.length }}个标签</view>
                        <view class="sms-data-tip">如标签关联的用户没有绑定手机号，将不会发送短信。</view>
                    </uni-forms-item>
                    <uni-forms-item label="任务名称" name="name" required
                        :rules="[{ required: true, errorMessage: '请输入任务名称' }]">
                        <uni-easyinput v-model="smsDataModel.name" placeholder="请输入任务名称，例如 “放假通知”" />
                    </uni-forms-item>
                    <uni-forms-item required label="短信模板" name="templateId"
                        :rules="[{ required: true, errorMessage: '请选择短信模板' }]">
						<template v-if="!smsTemplateLoading">
							<view v-if="smsTemplate.length">
								<uni-data-select class="type m" placeholder="请选择短信模板" size="mini" :clear="false"
									:localdata="smsTemplate" v-model="smsDataModel.templateId"
									@change="onSmsTemplateSelected">
								</uni-data-select>
								<view class="sms-data-tip">
									导入短信模版参考<a class="a-link" href="https://uniapp.dcloud.net.cn/uniCloud/admin.html#群发短信" target="_blank">教程</a>；若有新的短信模版，可<text @click="chooseFile"
										class="a-link">点此导入</text>
									</view>
							</view>
							<view v-else>
								<button @click="chooseFile" type="primary" style="width: 120px;"
									size="mini">上传短信模板</button>
								<view class="sms-data-tip">当前未导入短信模板，请从dev.dcloud.net.cn的短信-<a href="https://dev.dcloud.net.cn/pages/sms/template" target="_blank">模板配置</a>中导出短信模版，并在此导入。教程<a href="https://uniapp.dcloud.net.cn/uniCloud/admin.html#batch-sms" target="_blank">详见</a></view>
							</view>
						</template>
						<template v-else>
							模板加载中...
						</template>
                    </uni-forms-item>
                    <uni-forms-item label="短信内容" v-if="smsTemplateContent">
                        <view class="form-item-flex-center">{{smsTemplateContent}}</view>
                    </uni-forms-item>
                    <uni-forms-item label="模板变量配置" :error-message="smsTemplateDataErrorMessage"
                        v-if="smsDataModel.templateData.length">
                        <view class="sms-data-item" :key="template.field"
                            v-for="(template, index) in smsDataModel.templateData">
                            <uni-easyinput class="field m" v-model="template.field" placeholder="字段" :clearable="false"
                                :disabled="true" style="width: 120px;flex:none;" />
                            <uni-easyinput class="value m" v-model="template.value"
                                placeholder="例 {uni-id-users.username}" :clearable="false" />
                        </view>
                        <view class="sms-data-tip">短信变量支持固定值和数据表查询两种方式；固定值如：各位同事，数据表查询如：{uni-id-users.username}；请注意，若使用数据表查询方式，目前仅支持查询 uni-id-users 表；并注意确保数据库中查询字段值不为空，否则短信将发送失败。</view>
                    </uni-forms-item>
                </uni-forms>
                <view class="uni-group">
                    <button @click="sendSms(true)" class="uni-button">预览</button>
                    <button @click="sendSms()" class="uni-button" type="primary">提交</button>
                </view>
            </view>
            <uni-icons type="closeempty" size="24" class="close" @click="close"></uni-icons>
        </uni-popup>
        <uni-popup ref="previewPopup" type="center" :is-mask-click="false">
            <view class="sms-manager preview">
                <view class="sms-manager--header mb">
                    <view>短信预览</view>
                    <view class="sub-title">仅预览第一条短信内容</view>
                </view>
                <view class="content">
                    <view v-for="(content,index) of smsPreviewContent" :key="index">{{content}}</view>
                    <view class="length">短信字数：<text class="num">{{smsPreviewContent.length ? smsPreviewContent[0].length : 0}}</text>字</view>
                </view>
                <view class="tip">
                    <view>说明：</view>
                    <view>若从数据表中查询，字段内容长度会影响总字数，短信字数＝短信签名字数+短信内容字数。</view>
                    <view>短信长度不超过70个字，按照一条短信计费；超过70个字，按照67字/条拆分成多条计费。</view>
                </view>
                <view class="uni-group">
                    <button @click="$refs.previewPopup.close()" class="uni-button">关闭</button>
                </view>
            </view>
        </uni-popup>
    </view>
</template>

<script>
const uniSmsCo = uniCloud.importObject('uni-sms-co')

export default {
    name: 'batchSms',
    props: {
        // 发送类型 user|userTags
        toType: String,
        // 接收者 user=user._id, userTags=tag.id
        receiver: {
            type: Array,
            default() {
                return []
            }
        },

    },
    data() {
        return {
			smsTemplateLoading: false,
            smsTemplate: [],
            smsTemplateDataErrorMessage: '',
            smsDataModel: {
                name: '',
                templateId: '',
                templateData: []
            },
            smsTemplateContent: '',
            smsPreviewContent: [],
        }
    },
    computed: {
        isSelectedReceiver() {
            return !!this.receiver.length
        },
        sendAll() {
            return !this.isSelectedReceiver || this.toType === 'userTags'
        }
    },
    watch: {
        smsDataModel: {
            handler(smsDataModel) {
                if (!smsDataModel.templateId) return ''

                const template = this.smsTemplate.find(template => template.value === smsDataModel.templateId)
                let content = smsDataModel.templateData.reduce((res, param) => {
                    const reg = new RegExp(`\\$\\{${param.field}\\}`)
                    return res.replace(reg, ($1) => param.value || $1)
                }, template.content)

                this.smsTemplateContent = `【${template.sign}】${content}`
            },
            deep: true
        }
    },
    methods: {
        popupChange(e) {
            if (!e.show) this.reset()
        },
        open() {
            this.$refs.smsPopup.open()
			this.loadSmsTemplate()
        },
        close() {
            this.reset()
            this.$refs.smsPopup.close()
        },
		async loadSmsTemplate () {
			if (this.smsTemplate.length > 0 || this.smsTemplateLoading) return

			this.smsTemplateLoading = true

			try {
				const uniSmsCo = uniCloud.importObject('uni-sms-co', {customUI: true})
				const res = await uniSmsCo.template()
				this.smsTemplate = res.map(item => ({
					...item,
					value: item._id,
					text: item.name,
				}))
			} finally {
				this.smsTemplateLoading = false
			}
		},
        onSmsTemplateSelected(templateId) {
            const current = this.smsTemplate.find(template => template.value === templateId)

            if (!current) return

            const reg = new RegExp(/\$\{(.*?)\}/g)
            let templateVars = []
            let _execResult

            while (_execResult = reg.exec(current.content)) {
                const param = _execResult[1]

                if (param) {
                    templateVars.push({
                        field: param,
                        value: ''
                    })
                }
            }

            this.smsDataModel.templateData = templateVars
        },
        async sendSms(isPreview = false) {
            const values = await this.$refs.smsForm.validate()
            const receiver = this.receiver

            for (const template of this.smsDataModel.templateData) {
                if (!template.value) {
                    this.smsTemplateDataErrorMessage = '字段/值不可为空'
                    return
                }
            }
            this.smsTemplateDataErrorMessage = ''

            if (isPreview) {
                const res = await uniSmsCo.preview(
                    {
                        all: this.sendAll,
                        type: this.toType,
                        receiver
                    },
                    values.templateId,
                    this.smsDataModel.templateData
                )

                if (res.errCode === 0) {
                    this.smsPreviewContent = res.list
                    this.$refs.previewPopup.open()
                    return
                }
            }

            uni.showModal({
                title: '发送确认',
                content: `短信${this.sendAll ? '将发送给所有用户' : `预计发送${this.receiver.length}人`}，确定发送？`,
                success: async (e) => {
                    if (e.cancel) return

                    const res = await uniSmsCo.createSmsTask({
                        all: this.sendAll,
                        type: this.toType,
                        receiver
                    },
                        values.templateId,
                        this.smsDataModel.templateData, {
                        taskName: values.name
                    }
                    )

                    if (res.taskId) {
                        uni.showModal({
                            content: '短信任务已提交，您可在DCloud开发者后台查看短信发送记录',
                            confirmText: '立即查看',
                            cancelText: '关闭',
                            success: (e) => {
                                if (e.cancel) {
                                    this.reset()
                                    this.$refs.smsPopup.close()
                                } else {
                                    // #ifdef H5
                                    window.open('https://dev.dcloud.net.cn/#/pages/sms/sendLog', '_blank')
                                    // #endif
                                    // ifndef H5
                                    this.reset()
                                    this.$refs.smsPopup.close()
                                    // endif
                                }
                            }
                        })
                    }
                }
            })
        },
        chooseFile() {
            if (typeof window.FileReader === 'undefined') {
                uni.showModal({
                    content: '当前浏览器不支持文件上传，请升级浏览器重试',
                    showCancel: false
                })
                return
            }

            uni.chooseFile({
                count: 1,
                extension: ['.json'],
                success: ({ tempFiles }) => {
                    if (tempFiles.length <= 0) return
                    const [file] = tempFiles
                    const reader = new FileReader()

                    reader.readAsText(file)
                    reader.onload = () => this.parserFileJson(null, reader.result)
                    reader.onerror = () => this.parserFileJson(reader.error)
                },
                fail: () => {
                    uni.showModal({
                        content: '打开选择文件框失败',
                        showCancel: false
                    })
                }
            })
        },
        async parserFileJson(error, fileContent) {
            if (error) {
                console.error(error)
                uni.showModal({
                    content: '文件读取失败，请重新上传文件',
                    showCancel: false
                })
                return
            }

            let templates = []
            try {
                templates = JSON.parse(fileContent)
            } catch (e) {
                console.error(e)
                uni.showModal({
                    content: '短信模板解析失败，请检查模板格式',
                    showCancel: false
                })
                return
            }

            const res = await uniSmsCo.updateTemplates(templates)
            if (res.errCode === 0) {
                uni.showModal({
                    content: '短信模板更新成功',
                    showCancel: false,
                    success: () => {
						this.loadSmsTemplate()
                    }
                })
            }
        },
        reset() {
            this.smsDataModel.name = ''
            this.smsDataModel.templateId = ''
            this.smsDataModel.templateData = []
            this.smsPreviewContent = []
            this.smsTemplateContent = ''
        }
    }
}
</script>

<style lang="scss">
@import '@/uni_modules/uni-scss/variables.scss';

.a-link {
    cursor: pointer;
    color: $uni-primary;
    text-decoration: none;
}

.close {
    position: absolute;
    right: 20px;
    top: 20px;
    cursor: pointer;
}

.sms-manager {
    width: 570px;
    background: #fff;
    padding: 30px;
    border-radius: 5px;
    &.preview {
        width: 550px;
    }
    &--header {
        text-align: center;
        font-size: 22px;

        &.mb {
            margin-bottom: 50px;
        }
        .sub-title {
            margin-top: 5px;
            font-size: 16px;
            color: #999;
        }
    }
    .content {
        margin-top: 20px;
        font-size: 16px;
        line-height: 1.5;
        .length {
            text-align: right;
            font-size: 13px;
            margin-top: 20px;
            .num {
                color: red;
            }
        }
    }
    .tip {
        border-top: #ccc solid 1px;
        padding-top: 20px;
        margin-top: 20px;
        line-height: 1.7;
        font-size: 13px;
		color: #999;
    }
}

.sms-data-item {
    display: flex;
    align-items: center;
    margin-top: 10px;

    &:first-child {
        margin-top: 0;
    }

    .m {
        margin: 0 5px;

        &:first-child {
            margin-left: 0;
        }

        &:last-child {
            margin-right: 0;
        }
    }

    //.options {
    //  display: flex;
    //  align-content: center;
    //}
    .field {
        // flex: 1;
    }

    .type {
        width: 100px;
        flex: none;
    }

    .value {
        // width: 80px;
    }

    .add,
    .minus {
        cursor: pointer;
    }
}

.sms-data-tip {
    color: $uni-info;
    font-size: 12px;
    margin-top: 5px;
}

.form-item-flex-center {
    height: 100%;
    display: flex;
    align-items: center;
}
</style>
